package com.game.World.Logical;

import java.io.IOException;
import java.util.Random;


public class LogicalLevel {
	
	private Room gameField;
	
	private LevelOptions options;

	
	public LogicalLevel(LevelOptions opt) {
		this.options = opt;
	}
	
	
	public void generic() throws IOException{
		
		options.setOptions();
		
		gameField = new Room(options.square,options.square);
		
		Random rand = new Random();
		
		
		/**
		 * Step 1
		 * Build a one chamber
		 */
		
		
		int small_chambers = options.small_chambers;
		int middle_chambers = options.middle_chambers;
		int big_chambers = options.big_chambers;
		int halls_count = options.hall_count;
		
		int size = 0;
		small_chambers--;
		
		Room firstChamber = ChamberCreator.getChamber(size, rand.nextInt(ChamberCreator.CHAMBERS_COUNT));
		
		boolean firstChamberBuild = false;
		
		do {
			int x = rand.nextInt(gameField.getWidth());
			int y = rand.nextInt(gameField.getHeight());
			if (gameField.canBuild(firstChamber, x, y)) {
			
				gameField.Build(firstChamber, x, y);
				firstChamberBuild = true;
			}
			
		} while(!firstChamberBuild);
		
		
		
		
		boolean all_is_done = false;
		boolean chambers_is_done = false;
		boolean halls_is_done = false;
		
		
		
		while (!all_is_done) {
			
			if (!halls_is_done) {
					
					DoorChecker existDoorChecker = new DoorChecker(gameField);
					
					boolean hall_is_correct = false;
					
					int number = 0;
					
					while (existDoorChecker.isDoorNext()&&!hall_is_correct) {
							
							boolean door_is_correct = false;
							
							if (number ==0)
								number = rand.nextInt(HallCreator.HALLS_COUNT); 
							else
								number ++;
							
							Coordinate gameCoord = existDoorChecker.getNextCoord();
							
							Room new_hall = HallCreator.getHall(number);
							
							DoorChecker hall_doors = new DoorChecker(new_hall);
							
							while (hall_doors.isDoorNext()&&!door_is_correct) {
									Coordinate hallCoord = hall_doors.getNextCoord();
									
									if (gameField.canBuild(new_hall, gameCoord.x - hallCoord.x, gameCoord.y - hallCoord.y)) {
										gameField.Build(new_hall, gameCoord.x - hallCoord.x, gameCoord.y - hallCoord.y);
										door_is_correct = true;
										hall_is_correct =true;
										
										gameField.instance[gameCoord.x][gameCoord.y] = 'D';
									}
								
							}
							
					}
					
					halls_count--;
					
					if (halls_count == 0)
						halls_is_done = true;
					
			}
			
			
			if (!chambers_is_done) {
				
				DoorChecker existDoorChecker = new DoorChecker(gameField);
				
				boolean chamber_is_correct = false;
				
				int number = 0;
				
				while (existDoorChecker.isDoorNext()&&!chamber_is_correct) {
						
						boolean door_is_correct = false;
						
						if (number ==0)
							number = rand.nextInt(HallCreator.HALLS_COUNT); 
						else
							number ++;
						
						Coordinate gameCoord = existDoorChecker.getNextCoord();
						
						Room new_chamber = ChamberCreator.getChamber(0,number);
						
						DoorChecker chamber_doors = new DoorChecker(new_chamber);
						
						while (chamber_doors.isDoorNext()&&!door_is_correct) {
								Coordinate chamberCoord = chamber_doors.getNextCoord();
								
								if (gameField.canBuild(new_chamber, gameCoord.x - chamberCoord.x, gameCoord.y - chamberCoord.y)) {
									gameField.Build(new_chamber, gameCoord.x - chamberCoord.x, gameCoord.y - chamberCoord.y);
									door_is_correct = true;
									chamber_is_correct =true;
									
									gameField.instance[gameCoord.x][gameCoord.y] = 'D';
								}
							
						}
						
				}
				
				small_chambers--;
				
				if (small_chambers == 0)
					chambers_is_done = true;
				
			}
			
			
			if (halls_is_done&&chambers_is_done)
				all_is_done = true;
			
		}
		
		
		
		
		DoorChecker existDoorChecker = new DoorChecker(gameField);
		existDoorChecker.reset();
		
		Coordinate coord = existDoorChecker.getNextCoord();
		
		gameField.instance[coord.x][coord.y] = 'S';
		
		existDoorChecker.setDoors(gameField);
		
		coord = existDoorChecker.getNextCoord();
		
		gameField.instance[coord.x][coord.y] = 'E';
		
		
		
		
		existDoorChecker.setDoors(gameField);
		
		while(existDoorChecker.isDoorNext()) {
			Coordinate c = existDoorChecker.getNextCoord();
				gameField.instance[c.x][c.y] ='*';
					
		}
		
		int small_x = gameField.getWidth();
		int big_x = 0;
		int small_y = gameField.getHeight();
		int big_y = 0;
		
		for (int j=0; j < gameField.getHeight(); j++)
			for (int i=0; i < gameField.getWidth(); i++) {
				if (gameField.instance[i][j]!=' ') {
					if (i<small_x)
						small_x = i;
					if (i>big_x)
						big_x = i;
					if (j<small_y)
						small_y = j;
					if (j>big_y)
						big_y = j;
				}
			}
		
		gameField = gameField.Cut(small_x, big_x, small_y, big_y);
				
	
	}
	
	
	/**
	 * Method that returns level
	 * @return level (Room)
	 */
	public Room getRoom() {
		return gameField;
	}

}